﻿/*
* Description: 驱动打点
*/
#ifndef DRIVER_REPORT_H
#define DRIVER_REPORT_H
#include <Windows.h>
#include <mutex>
#include <condition_variable>
#include <vector>
#include <map>
#include <thread>
#include <sstream>
#include "singleton.h"
#include "process_detect.h"
#include "rpc_service/sendto_host.h"

namespace DFX {

struct DriverReportInfo {
    // 发布名称
    std::string publishName = "";
    // 驱动名称
    std::string driverName = "";
    // 驱动版本
    std::string driverVersion = "";
    // 驱动状态
    std::string driverStatus = "";
    // 驱动错误码
    std::string driverErrCode = "";
};

const std::string VIOSTOR = "viostor.inf";
const std::string NETKVM = "netkvm.inf";
const std::string SCREAM = "scream.inf";
const std::string PVPANIC_PCI = "pvpanic-pci.inf";
const std::string VIOFS = "viofs.inf";
const std::string VIOGPUDO = "viogpudo.inf";
const std::string VIOINPUT = "vioinput.inf";
const std::string VIOSER = "vioser.inf";
const std::string SVGAMPWDDM = "svgampwddm.inf";
const std::string BALLOON = "balloon.inf";
const std::string HWFS = "hwfs.inf";
const std::string IVSHMEM = "ivshmem.inf";
const std::string APP_FILTER = "app_filter_driver.inf";

const std::string BASE_PATH = "C:\\ProgramData\\VMAgent\\";
const std::string VIOSTOR_PATH = "driver0\\viostor\\viostor.inf";
const std::string NETKVM_PATH = "driver1\\netkvm\\netkvm.inf";
const std::string PVPANIC_PCI_PATH = "driver1\\pvpanic\\pvpanic-pci.inf";
const std::string VIOFS_PATH = "driver1\\viofs\\viofs.inf";
const std::string VIOGPUDO_PATH = "driver1\\viogpu\\viogpudo.inf";
const std::string VIOINPUT_PATH = "driver1\\vioinput\\vioinput.inf";
const std::string VIOSER_PATH = "driver1\\vioserial\\vioser.inf";
const std::string SVGAMPWDDM_PATH = "driver1\\wddm\\svgampwddm.inf";
const std::string IVSHMEM_PATH = "driver2\\ivshmem\\ivshmem.inf";
const std::string BALLOON_PATH = "driver2\\balloon\\balloon.inf";
const std::vector<std::string> APP_FILTER_CMD = {
    "@echo off",
    "echo %date% %time% - install APP_FILTER driver",
    "cd %PROGRAMDATA%\\VMAgent\\driver2\\app_filter",
    "devcon-arm64.exe remove \"root\\app_filter_driver\"",
    "devcon-arm64.exe install app_filter_driver\\app_filter_driver.inf \"root\\app_filter_driver\"",
    "del %0",
};

const std::vector<std::string> HWFS_CMD = {
    "@echo off",
    "echo %date% %time% - install HWFS driver",
    "cd %PROGRAMDATA%\\VMAgent\\driver2\\hwfs",
    "devcon-arm64.exe remove \"root\\hwfs\"",
    "devcon-arm64.exe install hwfs\\hwfs.inf \"root\\hwfs\"",
    "rundll32.exe hwfs\\hwfs_np.dll,HWFSInstall",
    "del %0",
};

const std::vector<std::string> SCREAM_CMD = {
    "@echo off",
    "echo %date% %time% - install Scream driver",
    "cd %PROGRAMDATA%\\VMAgent\\driver2\\scream",
    "helpers\\devcon-arm64.exe remove *Scream",
    "helpers\\devcon-arm64.exe install driver\\arm64\\Scream.inf *Scream",
    "del %0",
};

const std::map<std::string, std::string> infMap = {
    {VIOSTOR, VIOSTOR_PATH},
    {NETKVM, NETKVM_PATH},
    {PVPANIC_PCI, PVPANIC_PCI_PATH},
    {VIOFS, VIOFS_PATH},
    {VIOGPUDO, VIOGPUDO_PATH},
    {VIOINPUT, VIOINPUT_PATH},
    {VIOSER, VIOSER_PATH},
    {SVGAMPWDDM, SVGAMPWDDM_PATH},
    {BALLOON, BALLOON_PATH},
    {IVSHMEM, IVSHMEM_PATH},
};

const std::map<std::string, std::vector<std::string>> cmdMap = {
    {HWFS, HWFS_CMD},
    {SCREAM, SCREAM_CMD},
    {APP_FILTER, APP_FILTER_CMD},
};

const std::vector<std::string> DRIVER_NAMES = {
    VIOSTOR, NETKVM, SCREAM, PVPANIC_PCI, VIOFS, VIOGPUDO, VIOINPUT,
    VIOSER, SVGAMPWDDM, BALLOON, HWFS, IVSHMEM, APP_FILTER
    };

const int REPORT_INTERVAL_SECONDS = 300;
const int ARRAY_SIZE = 128;
const std::string PUBLISH_NAME_KEY = "发布名称";
const std::string ORIGIN_NAME_KEY = "原始名称";
const std::string DRIVER_NAME_KEY = "驱动程序名称";
const std::string DRIVER_VERSION_KEY = "驱动程序版本";
const std::string DRIVER_STATUS_KEY = "状态";
const std::string DRIVER_ERRCODE_KEY = "问题代码";
const std::string DRIVER_STATUS_ERR = "问题";
const std::string DRIVER_STATUS_DISABLE = "已禁用";
const std::string DRIVER_ERRCODE_DISABLE = "22"; // 设备已停用
const std::string DRIVER_ERRCODE_UNINSTALL = "28"; // 设备的驱动程序未安装
const std::string EVENT_DRIVER_LOST = "SA_VM_DRIVER_LOST";
const std::string EVENT_DRIVER_ERROR = "SA_VM_DRIVER_DY_MARK";

class DriverReport {
public:
    DriverReport() = default;
    ~DriverReport() = default;
    void Init(std::shared_ptr<WINCONTROL::SendToHost> sendtoHost);
    void Deinit();
    void ReportData();
private:
    void FillReportLostData(const std::vector<DriverReportInfo> onlineDrivers);
    void RecordLostBiLog(const std::vector<std::string> &lostDrivers);
    std::string ToJsonString(const DriverReportInfo &driverReportInfo);
    std::vector<DriverReportInfo> GetDriversInfo();
    std::vector<std::string> GetLostDriversInfo(const std::vector<DriverReportInfo> &onlineDrivers);
    void FillReportStatusData(const std::vector<DriverReportInfo> onlineDrivers);
    void RecordStatusBiLog(const std::vector<DriverReportInfo> &driversStatusInfo);
    std::vector<DriverReportInfo> GetDriversStatusInfo();
    std::vector<DriverReportInfo> GetDriversErrorInfo(const std::vector<DriverReportInfo> &onlineDrivers,
        const std::vector<DriverReportInfo> &driversStatusInfo);
    void InstallLostDrivers(const std::vector<std::string> &lostDrivers);
    std::shared_ptr<WINCONTROL::SendToHost> m_sendtoHost{ nullptr };
    DriverReportInfo AssembleDriverErrorInfo(const DriverReportInfo &info, const std::string &errCode);
    void CheckInstallLostDrivers();
};

#define DRIVER_REPORT SingletonNew<DFX::DriverReport>::GetInstance()
}  // namespace DFX
#endif